home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
sr
/
info.lha
/
info-sr.1992
/
000019_eric@cs.sfu.ca _Thu Nov 19 14:27:36 1992.msg
< prev
next >
Wrap
Text File
|
1993-07-24
|
8KB
|
315 lines
Received: from aquarius.cs.sfu.ca by optima.cs.arizona.edu (5.65c/15) via SMTP
id AA17906; Thu, 19 Nov 1992 15:29:07 MST
Received: by aquarius.cs.sfu.ca id AA27946
(5.65c/IDA-1.4.4 for info-sr@cs.arizona.edu); Thu, 19 Nov 1992 14:27:36 -0800
Date: Thu, 19 Nov 1992 14:27:36 -0800
From: Eric Kolotyluk <eric@cs.sfu.ca>
Message-Id: <199211192227.AA27946@aquarius.cs.sfu.ca>
To: info-sr@cs.arizona.edu
Subject: Priorities in SR
I'm working on an SR program to simulate the interaction of a disk,
disk controller, and computer system. I started off using the Discrete
Event Simulation example program in Chapter 18 od the SR Programming
Language book. I wasn't very happy with the implementation of the
Scheduler because of having to keep track of active processes, etc.
When I realized that the sole point of keeping track of active
processes was to lock-out the Scheduler while other tasks were still
ready to run, I felt the same effect could be achieved by simply running
the Scheduler at a lower process priority than every other process in
the program.
I reworked my program to explicitly set the scheduler's priority lower
than everything else, but it has only partially the desired effect. In
particular I think I'm seeing a situation where the scheduler is still
running when other processes of higher priority are definitely `ready'.
Could someone please tell me if this a `bug' in SR's dispatching
mechanisms or a misunderstanding on how I read the description in the
book.
What follows is a copy of the program and some sample output. The point
where I think something is wrong is right after the main resource starts
up a couple of tasks. Each task calls scheduler.delay and the delay proc
registers both of these. At this point control should transfer back to
the main resource so it can call delay, but in fact the event_manager
in the scheduler imediately processes its event list... This should
not happen if the scheduler is `really' running at a lower priority than
the main process.
A further troubling point in the example output below suggests that the
task with the largest delay gets the first go_ahead???
./disk
main: my priority = 1
event_manager: my priority = 0
controller: my priority = 1
main: creating tasks...
task: my priority = 1
scheduler: delay = 0.00000 9524.97 9524.97
Task 1 created.
task: my priority = 1
scheduler: delay = 0.00000 3077.64 3077.64
event_manager: go ahead 9524.97
event_manager: go ahead 3077.64
Task 2 created.
scheduler: delay = 3077.64 1.00000e+08 1.00003e+08
event_manager: go ahead 1.00003e+08
disk seek to cylinder 564
scheduler: delay = 1.00003e+08 1575.00 1.00005e+08
main: shutting down
event_manager: go ahead 1.00005e+08
disk seek to cylinder 1092
scheduler: delay = 1.00005e+08 1645.21 1.00006e+08
scheduler: delay = 1.00005e+08 9938.55 1.00015e+08
event_manager: go ahead 1.00006e+08
event_manager: go ahead 1.00015e+08
Controller: disk_manager shutting down
scheduler: delay = 1.00015e+08 31.9262 1.00015e+08
event_manager: go ahead 1.00015e+08
Scheduler: event_manager shutting down
RTS warning: blocked process: Task.task
RTS warning: blocked process: Task.task
#########################################################################
# #
# Disk Simulation Program #
# #
#########################################################################
global System
import Scheduler, Controller
const tasks := 2
var scheduler: cap Scheduler
var controller1: cap Controller
var active_tasks: int := tasks
end System
#########################################################################
# #
# Scheduler resource #
# #
#########################################################################
resource Scheduler
op time() returns t: real
op delay(t: real)
op shutdown()
import System
body Scheduler()
op event_list(go_ahead: cap(); t: real)
var clock := 0.0 # the simulation clock
process event_manager
var priority: int
setpriority(-1)
priority := mypriority()
write("event_manager: my priority =", priority)
do true ->
in time() returns t ->
t := clock
[] event_list(go_ahead,t) by t ->
clock := t
write("event_manager: go ahead", t)
send go_ahead()
setpriority(-1)
[] shutdown() ->
exit
ni
od
write("Scheduler: event_manager shutting down")
end event_manager
# provide a simple call interface for processors
proc delay(t)
write("scheduler: delay =", clock, t, clock+t)
op go_ahead()
send event_list(go_ahead, t+clock)
receive go_ahead()
end
end Scheduler
#########################################################################
# #
# Disk resource #
# #
#########################################################################
#
# The Disk resource simulates a raw disk drive in terms of seek time and
# rotational latency.
resource Disk
op seek(cyl: int), read(sec: int)
import System
body Disk(
cylinders: int;
tracks: int;
sectors: int;
bytes: int;
rpm: real;
seekMin: real;
seekAvg: real;
seekMax: real)
var cylinder: int := 0 /* Current cylinder position (0 = outermost) */
var theta: real := 0.0 /* Current Angle of the disk platters */
var velocity: real := cylinders / (seekMax - seekMin)
proc seek(cyl)
var distance: int := abs(cylinder - cyl)
write("disk seek to cylinder", cyl)
scheduler.delay( distance * velocity + seekMin )
end seek
proc read(sec)
end read
end Disk
#########################################################################
# #
# Controller resource #
# #
#########################################################################
resource Controller
op blocks() returns highest_block: int
op block_request(block: int)
op shutdown()
import System, Disk
body Controller()
var disk: cap Disk
disk := create Disk(2460, 15, 66, 512, 5400, 1500, 10000, 20000)
proc blocks() returns highest_block
highest_block := 2460 * 15 * 66 - 1
end blocks
process disk_manager
var priority: int
priority := mypriority()
write("controller: my priority =", priority)
do true ->
in block_request(block) ->
disk.seek(block / 15 / 66)
[] shutdown() ->
exit
ni
od
write("Controller: disk_manager shutting down")
end disk_manager
end Controller
#########################################################################
# #
# Task resource #
# #
#########################################################################
resource Task
import System, Controller
body Task(accesses: int)
var cblocks: int := controller1.blocks()
process task
var priority: int
priority := mypriority()
write("task: my priority =", priority)
fa f := 1 to accesses ->
scheduler.delay(random(10000.0))
controller1.block_request(int(random(cblocks)))
af
--active_tasks
end task
end Task
#########################################################################
# #
# main resource #
# #
#########################################################################
resource main()
import System, Scheduler, Controller, Task
const stime: int := 100000000 # Simulation Time, 100 Seconds
var task[tasks]: cap Task
var i: int
var priority: int
priority := mypriority()
write("main: my priority =", priority)
scheduler := create Scheduler()
controller1 := create Controller()
write("main: creating tasks...")
fa i := 1 to tasks ->
task[i] := create Task(10)
write("Task", i, "created.")
af
scheduler.delay(stime)
write("main: shutting down")
controller1.shutdown()
scheduler.shutdown()
end main